package com.scalar.chiptrack.sales.actions;

import java.util.ArrayList;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.alarms.Alarm;
import com.scalar.chiptrack.alarms.dao.AlarmDAO;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.sales.LineItem;
import com.scalar.chiptrack.sales.SalesOrder;
import com.scalar.chiptrack.sales.dao.NewSalesOrderDAO;
import com.scalar.chiptrack.sales.dao.SalesOrderDAO;
import com.scalar.chiptrack.sales.dao.CustomerDAO;
import com.scalar.chiptrack.sales.dao.SalesDAO;
import com.scalar.chiptrack.sales.forms.SplitSalesOrderForm;
import com.scalar.chiptrack.users.User;


/**
 * @author Prabhanjan Kumar .V
 * @version $Revision: 1.7 $ $Date: 2010/09/17 18:13:48 $
 */

public final class SplitSalesOrderAction extends ChipTrackAction
{

    private static final String ACTION_NAME = "/changeOrder.do";  // Added by Basha (08/08/2003)
    public static SplitSalesOrderForm subform;
    // ----------------------------------------------------- Instance Variables


    // --------------------------------------------------------- Public Methods


    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     *
     * @param mapping The ActionMapping used to select this instance
     * @param form The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception Exception if business logic throws an exception
     */
    public ActionForward execute ( ActionMapping mapping,
                                   ActionForm form,
                                   HttpServletRequest request,
                                   HttpServletResponse response )
            throws Exception
    {

        // Extract attributes and parameters we will need
        subform = ( SplitSalesOrderForm ) form;

        int isSample = 1; //default set to salesOrder
        if ( ( request.getParameter ( "isSample" ) != null ) && ( !request.getParameter ( "isSample" ).equals ( "null" ) ) )
        {
            isSample = Integer.parseInt ( request.getParameter ( "isSample" ) );
        }

        String action = request.getParameter ( "action" );
        // added by veeru
        if("splitLineItems".equals(action))
        {
            action = "";
        }
        //Get the session, to retrieve the values
        HttpSession session = request.getSession ();
        User user = ( User ) session.getAttribute ( SessionKeys.USER_KEY );


        if ( action == null )
        {
            action = "";
        }
        if ( user == null )
        {
            //session.setAttribute ( SessionKeys.SOURCE_PAGE_KEY, ACTION_NAME + "?" + request.getQueryString () );
            session.setAttribute ( SessionKeys.SOURCE_PAGE_KEY, ACTION_NAME + "?" + "isSample="+request.getParameter("isSample"));
            return ( mapping.findForward ( "login" ) );
        }

        /** Commented by rohan on April 21st 2004
		// Basha on Feb 07, 2004
        if( Constants.FINANCE_INTEGRATION_TYPE_GREAT_PLAINS.equalsIgnoreCase( ConfigManager.getFinanceIntegrationType() ) == true )
        {
            return new GPSplitSalesOrderAction().execute( mapping, form, request, response );
        }
        // Great Plains Re-direction -----------------------------------------------------------
        */

        if ( request.getParameter ( "salesOrderId" ) != null )
        {
            DBTransaction dbTransaction = null;
            String salesOrderId     = request.getParameter ( "salesOrderId" );
            ArrayList lineItems     = SalesOrderDAO.loadOrderLineItemsForSplitting ( dbTransaction, Integer.parseInt ( salesOrderId ) );
            int customerId          = NewSalesOrderDAO.getCustomerID( null, salesOrderId);
            int odmId               = NewSalesOrderDAO.getOdmId( Integer.parseInt ( salesOrderId ) );
            //SalesOrderDAO.loadCustomerPartNumbersForLineItems( null, lineItems, customerId, odmId );
            subform.setSalesOrderId( salesOrderId );
            subform.setCustomerName( CustomerDAO.getCustomerName( null, customerId ) );

            if ( lineItems.size () > 0 )
            {
                subform.setSalesOrderNo ( ( ( LineItem ) lineItems.get ( 0 ) ).getSalesOrderNo () );
            }

            /*  The following code is added by Murali Krishna Yengala on January 11 2005.
                If the session attribute "frmPending" is present, the request has come from pending orders.
                If the request has come from pending orders, line items which are under HOLD must only be shown.
                The following snippet does that.
            */
            if((request.getParameter("frmPending") != null ) || ( request.getAttribute("frmPending")!=null))
            {
                ArrayList tmpLineItems = new ArrayList();
                for(int i=0; i<lineItems.size(); i++)
                {
                    LineItem lineItem = (LineItem)lineItems.get(i);
                    if( ("HOLD".equals(lineItem.getFinalStatus())))
                    {
                        tmpLineItems.add(lineItem);
                    }
                }
                request.setAttribute("frmPending","1");
                lineItems = tmpLineItems;
            }
            else //request is from change order screen. We should not show shipped lineitems in split sales order screen.
			{
				ArrayList tmpLineItems = new ArrayList();
                for(int i=0; i<lineItems.size(); i++)
                {
                    LineItem lineItem = (LineItem)lineItems.get(i);
                    if( ("SHIPPED".equalsIgnoreCase( lineItem.getFinalStatus() ) ) == false )
                    {
                        tmpLineItems.add(lineItem);
                    }
                }
                lineItems = tmpLineItems;
			}
            session.setAttribute ( "lineItems", lineItems );
        }

        if ( "splitSalesOrder".equals ( action ) )
        {
            ArrayList lineItemsAfterSplit = splitLineItems ( request, ( ArrayList ) session.getAttribute ( "lineItems" ), subform );
            request.setAttribute ( "lineItemsAfterSplit", lineItemsAfterSplit );
        }

        if ( "confirmSplitSalesOrder".equals ( action ) )
        {
            DBTransaction dbTransaction = null;
            HashMap info   = new HashMap ();
            HashMap errors = new HashMap ();
            Alarm alarm                 = null;
            ArrayList previousLineItems = null;
            int lineItemNo              = 0;
            int salesOrderId            = 0;
            int customerId              = 0;
            String salesOrderNo         = null;
            String salesOrderStatus     = null;
            String customerName         = null;
            boolean isSampleBoolean     = false;
            int sid                     = 0;

            if( isSample == 0 )
            {
                isSampleBoolean = true;
            }

            boolean success = false;
            try
            {
                previousLineItems   = ( ArrayList ) session.getAttribute ( "lineItems" );

                if( previousLineItems != null && previousLineItems.size () > 0 )
                {
                    sid = ( ( LineItem ) previousLineItems.get ( 0 ) ).getSalesOrderId ();
                    subform.setSalesOrderId ( Integer.toString ( sid ) );
                    subform.setSalesOrderNo ( ( ( LineItem ) previousLineItems.get ( 0 ) ).getSalesOrderNo () );
                    customerId = NewSalesOrderDAO.getCustomerID( null, sid + "" );
                }

                dbTransaction = DBTransaction.getInstance ();
                dbTransaction.begin ();

                SalesOrderDAO.splitLineItems( dbTransaction, previousLineItems, user.getUserId () );

                success = true;
            }
            catch ( Exception e )
            {
                e.printStackTrace ();
            }
            finally
            {
                if ( success )
                {
                    dbTransaction.commit ();
                    info.put ( "Line Items have been split and saved successfully", null );
                    String changesSummary = "";
                    for (int i = 0; i < previousLineItems.size(); i++) {
                        LineItem lineItem = (LineItem) previousLineItems.get(i);
                        if ( lineItem.isSplit() ) {
                            lineItemNo = lineItem.getLineItemNo();
                            salesOrderId = lineItem.getSalesOrderId();
                            salesOrderNo = lineItem.getSalesOrderNo();
                            changesSummary += "<br> Line Item "+lineItemNo+" has been split into two line items";
                        }
                    }
                    try
                    {
                        alarm = SalesOrderDAO.updateAlarmForChangeOrder ( dbTransaction, "", salesOrderId, user );

                        //alarm.setRecipients ( AlarmDAO.loadRecipientsWithBoardKitChipAccess ( salesOrderId, alarm ) );

                        salesOrderStatus = SalesDAO.loadStatus( null, salesOrderId );
                        if( salesOrderStatus != null && salesOrderStatus.indexOf( Constants.SALESORDER_STATUS_HOLD ) >= 0  )
                        {
                            salesOrderStatus = Constants.SALESORDER_STATUS_HOLD;       
                        }
                        alarm.setSubject( "Sales Order Notification - SO No.: " + salesOrderNo + " - Customer: " + customerName + " - Status: " + salesOrderStatus + " -- UPDATED" );
                        alarm.notifyAllRecipients ( SalesOrder.getHtmlViewWithChangeSummary ( salesOrderId, changesSummary ) );
                    }
                    catch ( Exception ex )
                    {
                        ex.printStackTrace();
                        info.put ( "Email ", ERROR_IN_SENDING_MAILS_TO_APPROVERS );
                        info.put ( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
                        session.setAttribute ( SessionKeys.ERROR_REPORT_SUBJECT, " Error: Could not Send mails to Approvers " );
                        session.setAttribute ( SessionKeys.ERROR_REPORT, null );
                    }
                }
                else
                {
                    dbTransaction.rollback ();
                    errors.put ( "Line Items could not be split", null );
                }
            }
            if ( !info.isEmpty () )
                request.setAttribute ( SessionKeys.INFO_MESSAGES, info );
            if ( !errors.isEmpty () )
                request.setAttribute ( SessionKeys.ERROR_MESSAGES, errors );

            /*  The following code is added by Murali Krishna Yengala on January 11 2005.
                If the session attribute "frmPending" is present, the request has come from pending orders.
                The following code must not be processed if "frmPending" is present.
            */
            if( request.getParameter("frmPending") == null)
            {

                ArrayList lineItems = SalesOrderDAO.loadOrderLineItemsForSplitting ( null, sid );

                ArrayList newSplitLineItemList = newSplitLineItemList( previousLineItems, lineItems );

                if( newSplitLineItemList != null && newSplitLineItemList.size() > 0 && success )
                {
                    try
                    {
                        success = false;
                        dbTransaction = DBTransaction.getInstance ();
                        dbTransaction.begin ();

                        SalesOrderDAO.setCustomerHolds( dbTransaction, user, newSplitLineItemList, customerId , sid, isSampleBoolean );

                        success = true;
                    }
                    catch ( Exception e )
                    {
                        e.printStackTrace ();
                    }
                    finally
                    {
                        if( success )
                        {
                            dbTransaction.commit ();
                        }
                        else
                        {
                            dbTransaction.rollback ();
                        }
                    }
                }
                SalesOrder salesOrder = SalesOrderDAO.loadSalesOrder ( Integer.toString(sid) );
                int j = SalesOrderDAO.loadMaxLineItemNo ( salesOrder.getSalesOrderId () );
                ArrayList lineItemsFromChangeOrder = (ArrayList)session.getAttribute ("lineItemsFromChangeOrder");
                for( int i = 0; i < lineItemsFromChangeOrder.size(); i++)
                {
                    LineItem lineItem = (LineItem)lineItemsFromChangeOrder.get(i);
                    if(lineItem.getIsNewLineItem())
                    {
                        lineItem.setLineItemNo(j);
                        lineItems.add(lineItem);
                        j++;
                    }
                }
                session.setAttribute ( "maxLineItemNo", Integer.toString ( j ) );

                session.setAttribute ( "lineItems", lineItems );

                //return new ActionForward("/changeOrder.do?salesOrderId="+sid+"&isSample=1", false);
                return new ActionForward("/changeOrder.do?action=EditChangeOrder&salesOrderId="+sid+"&customerId="+subform.getCustomerId()+"&isSample="+request.getParameter("isSample")+"&isSplit=1", false);
            }
            else
            {
                /* "frmPending" session attribute is no more required. */
                request.removeAttribute("frmPending");
                return new ActionForward("/approveOrder.do?salesOrderId="+sid+"&isSample="+request.getParameter("isSample"),false);
            }

        }
        request.setAttribute ( "splitSalesOrderForm", subform );
        return ( mapping.findForward ( "success" ) );
    }

    // Added by Prabhanjan on 05 Jan 2004
    private static ArrayList splitLineItems ( HttpServletRequest request, ArrayList lineItems, SplitSalesOrderForm form )
    {

        ArrayList lineItemsAfterSplit = new ArrayList ();
        for ( int i = 0; i < lineItems.size (); i++ )
        {
            lineItemsAfterSplit.add ( lineItems.get ( i ) );
        }

        String[] lineItemId = request.getParameterValues ( "lineItemId" );
        String[] lineItemNo = request.getParameterValues ( "lineItemNo" );
        String[] quantity = request.getParameterValues ( "quantity" );
        String[] shippedQty = request.getParameterValues ( "shippedQty" );
        String salesOrderNo = form.getSalesOrderId ();
        String[] quantityToSplit = request.getParameterValues ( "qtyToSplit" );



        for ( int i = 0; i < lineItemNo.length; i++ )
        {
            LineItem previousLineItem = ( LineItem ) lineItems.get ( i );

            LineItem lineItem = ( LineItem ) lineItemsAfterSplit.get ( i );
            LineItem tempLineItem = new LineItem ();
            tempLineItem.setLineItemId ( lineItem.getLineItemId () );
            LineItem maxLineItem = ( LineItem ) lineItemsAfterSplit.get ( lineItemsAfterSplit.size () - 1 );

            tempLineItem.setLineItemNo ( maxLineItem.getLineItemNo () + 1 );

            tempLineItem.setManufacturingPartNo ( lineItem.getManufacturingPartNo () );
            tempLineItem.setDescription ( lineItem.getDescription () );
            tempLineItem.setCustomerPartNo( lineItem.getCustomerPartNo() );
            tempLineItem.setCustomerPartNo ( lineItem.getCustomerPartNo () );  //Added by Sarada to set Customer PartNo  after splitting
            tempLineItem.setIsTaxable ( lineItem.getIsTaxable () );
            tempLineItem.setRequestDate ( lineItem.getRequestDate () );
            tempLineItem.setScheduleDate( lineItem.getScheduleDate() ); // Added by Krishna Prasad on 12-Dec-2004
            tempLineItem.setUnitPriceAsDouble ( lineItem.getUnitPriceAsDouble () );
            tempLineItem.setIsExpedite( lineItem.getIsExpedite() );
            tempLineItem.setCustomPriceField1(lineItem.getCustomPriceField1());
            tempLineItem.setCustomTextField1(lineItem.getCustomTextField1());
            tempLineItem.setShippedQty ( 0 );

            if ( request.getParameter ( "split" + i ) != null )
            {
                int qtyToSplit = Integer.parseInt ( quantityToSplit[i].trim() );
                int qty = Integer.parseInt ( quantity[i].trim() );
                int shipQty = Integer.parseInt ( shippedQty[i].trim() );

                previousLineItem.setSplit ( true );
                previousLineItem.setSplitQty ( qtyToSplit );
                previousLineItem.setScheduleDate( lineItem.getScheduleDate() );
                if ( ( qtyToSplit > 0 ) && ( qtyToSplit < qty ) && ( qtyToSplit <= ( qty - shipQty ) ) )
                {
                    lineItem.setQuantity ( qty - qtyToSplit );
					//Modified by Sarada 6th April 2004 to restrict exponential values
					//lineItem.setAmount ( lineItem.getQuantity () * lineItem.getUnitPrice () );
                    lineItem.setAmountAsDouble ( lineItem.getQuantity () * lineItem.getUnitPriceAsDouble () );
                    tempLineItem.setQuantity ( qtyToSplit );
                    // Added by Prabhanjan on 12 Jan 2004
                    tempLineItem.setPoLineItemNo(lineItem.getPoLineItemNo());
                    //tempLineItem.setAmount ( tempLineItem.getQuantity () * tempLineItem.getUnitPrice () );
					tempLineItem.setAmountAsDouble ( tempLineItem.getQuantity () * tempLineItem.getUnitPriceAsDouble () );
                    lineItemsAfterSplit.add ( tempLineItem );
                }
            }
        }
        return lineItemsAfterSplit;
    }

    private static ArrayList newSplitLineItemList( ArrayList previousLineItemList, ArrayList dbLineItemList )
    {
        LineItem lineItem               = null;
        LineItem dbLineItem             = null;
        int prvLineItemListSize         = previousLineItemList.size();
        ArrayList newSplitLineItemList  = new ArrayList();
        newSplitLineItemList.addAll( dbLineItemList ); 
        for( int i = newSplitLineItemList.size() - 1; i >= 0 ; i-- )
        {
            dbLineItem = ( LineItem ) newSplitLineItemList.get ( i );

            dbLineItem.setLineItemSplited( true );

            for ( int j = 0; j < prvLineItemListSize; j++ )
            {
                lineItem = ( LineItem ) previousLineItemList.get ( j );

                if( dbLineItem != null && lineItem != null && dbLineItem.getLineItemId() == lineItem.getLineItemId() )
                {
                    newSplitLineItemList.remove(i);
                    break;
                }
            }
        }

        return newSplitLineItemList;
    }
}